/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.authorization.interceptor;

import com.bifrost.annotation.Authorization;
import com.bifrost.authorization.manager.TokenManager;
import com.bifrost.common.constant.SessionConstant;
import com.bifrost.exception.UnAuthorizationException;
import com.bifrost.util.CookieUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;

/**
 * 自定义拦截器，判断此次请求是否有权限
 *
 * @author bifrost
 * @version 1.0.0
 * @Date: 2017/10/9
 */
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    @Qualifier("defaultTokenManager")
    private TokenManager manager;

    @Value("${jwt.token.expire}")
    private int expire;

    public static final String UID = "uid";
    public static final String TOKEN = "token";
    //public static final String MERCHANT="merchant";

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        //如果不是映射到方法直接通过
        Authorization annotation;
        String appId = CookieUtils.getCookieValue(request,SessionConstant.APP_ID);
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(Authorization.class);
        } else {
            return true;
        }
        //如果有@Authorization注解，则需要验证token
        if (annotation == null) {
            return true;
        }
        String token=null;
        //如果参数中不存在token，则从session中获取token
        if(StringUtils.isBlank(token)){
            HttpSession session = request.getSession(true);
            Object tokenObject = session.getAttribute(SessionConstant.TOKEN);
            if(tokenObject!=null&&StringUtils.isNotBlank(tokenObject.toString())){
                token = tokenObject.toString();
            }
        }
        //从header中得到token
        /*token= request.getHeader(TOKEN);
        //如果header中不存在token，则从参数中获取token
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(TOKEN);
        }
        //如果参数中不存在token，则从Cookie中获取token
        if (StringUtils.isBlank(token)) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (int i = 0; i < cookies.length; i++) {
                    String name = cookies[i].getName();
                    if (name.equals(TOKEN)) {
                        token = cookies[i].getValue();
                    }
                }
            }
        }*/

        if (StringUtils.isBlank(token)) {
           if (StringUtils.isNotBlank(appId)) {
               String path = request.getContextPath().endsWith("/")?String.format("%sindex/%s",request.getContextPath(),appId):String.format("%s/index/%s",request.getContextPath(),appId);
               throw new UnAuthorizationException("重新登录",path);
           }
            throw new UnAuthorizationException("重新登录");
        }
        //验证token
        try {
            if (manager.checkToken(token, request)) {
                //重新设置cookie延期与token一样
                // CookieUtils.saveCookie(response, "token", token, expire * 24 * 3600);
                return true;
            } else {
                throw new UnAuthorizationException("token无效");
            }
        }catch (SignatureException | ExpiredJwtException e ){
            if (StringUtils.isNotBlank(appId)) {
                String path = request.getContextPath().endsWith("/")?String.format("%sindex/%s",request.getContextPath(),appId):String.format("%s/index/%s",request.getContextPath(),appId);
                throw new UnAuthorizationException("token无效",path);
            }
            throw new UnAuthorizationException("token无效");
        }
    }
}
